package com.gk.service.impl;

import com.gk.elasticsearch.repository.PoemRepository;
import com.gk.entity.Category;
import com.gk.entity.Poem;
import com.gk.mapper.PoemMapper;
import com.gk.service.PoemService;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 诗词信息操作的service
 */
@Service
@Transactional
public class PomServiceImpl implements PoemService {

    @Autowired
    private PoemMapper poemMapper;

    @Autowired
    private PoemRepository poemRepository;

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Override
    public List<Poem> findAll() {
        return poemMapper.findAll();
    }

    @Override
    public List<Poem> findByPage(Integer page, Integer size) {
        int start = (page - 1) * size;
        return poemMapper.findByPage(start, size);
    }

    @Override
    public Integer findTotalCounts() {
        return poemMapper.findTotalCounts();
    }

    @Override
    public void saveAll() {

        //清空所有文档
        poemRepository.deleteAll();

        //重新创建文档
        //从数据库中查出数据
        List<Poem> poemList = poemMapper.findAll();

        //将数据导入ES库
        poemRepository.saveAll(poemList);
    }

    @Override
    public void deleteAll() {

        //先查询Es中是否存在文档
        List<Poem> poemList = poemMapper.findAll();

        //如果存在文档就删除
        if (poemList.iterator().hasNext()){
            //清空所有文档
            poemRepository.deleteAll();
        } else {
            throw new RuntimeException("当前索引中已经没有任何文档!");
        }

    }

    @Override
    public List<Poem> findByKeywords(String content, String type, String author) throws IOException {

        List<Poem> list = new ArrayList<>();

        //创建搜索请求
        SearchRequest searchRequest = new SearchRequest("poems");

        //构建搜索对象
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        if (StringUtils.isEmpty(content)) {
            //设置为查询所有
            sourceBuilder.query(QueryBuilders.matchAllQuery());
        } else {
            //设置为多字段检索
            sourceBuilder.query(QueryBuilders.multiMatchQuery(content,"name", "content", "author", "authordes"));
        }

        //设置过滤条件
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        if (!StringUtils.isEmpty(type)) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("type", type));
        }
        if (!StringUtils.isEmpty(author)){
            boolQueryBuilder.filter(QueryBuilders.termQuery("author", author));
        }

        //指定过滤
        sourceBuilder.postFilter(boolQueryBuilder);
        //指定显示条数
        sourceBuilder.size(100);
        //设置高亮查询
        sourceBuilder.highlighter(new HighlightBuilder().field("*").requireFieldMatch(false).preTags("<span style='color:red;'>").postTags("</span>"));

        //搜索请求对象指定 搜索类型
        searchRequest.types("poem").source(sourceBuilder);

        //执行搜索
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();

        //高亮处理
        for (SearchHit hit : hits) {
            //原始文档封装
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            Poem poem = new Poem();
            poem.setId(hit.getId());
            poem.setName(sourceAsMap.get("name").toString());
            poem.setAuthor(sourceAsMap.get("author").toString());
            poem.setType(sourceAsMap.get("type").toString());
            poem.setContent(sourceAsMap.get("content").toString());
            poem.setHref(sourceAsMap.get("href").toString());
            poem.setAuthordes(sourceAsMap.get("authordes").toString());
            poem.getCategory().setName(sourceAsMap.get("category").toString());

            //高亮字段
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            //诗词名
            if (highlightFields.containsKey("name")) {
                poem.setName(highlightFields.get("name").fragments()[0].toString());
            }
            //作者
            if (highlightFields.containsKey("author")) {
                poem.setAuthor(highlightFields.get("author").fragments()[0].toString());
            }
            //内容
            if (highlightFields.containsKey("content")) {
                poem.setContent(highlightFields.get("content").fragments()[0].toString());
            }
            //作者简介
            if (highlightFields.containsKey("authordes")) {
                poem.setAuthordes(highlightFields.get("authordes").fragments()[0].toString());
            }
            list.add(poem);
        }

        return list;
    }
}
